﻿using Microsoft.Extensions.DependencyInjection;
using Modules.Project.Entitys;
using Modules.Reports;
using Modules.System.User;
using PetaPoco;
using PmSoft;
using PmSoft.ApplicationContext;
using PmSoft.Caching;
using PmSoft.DBContext;
using PmSoft.Entity;
using PmSoft.Repositories;
using PmSoft.Utilities;

namespace Modules.Project.Repositories;

/// <summary>
/// 项目解上锁记录仓储
/// </summary>
[UseDI(ServiceLifetime.Scoped)]
public class ProjectLockLogRepository : Repository<ProjectLockLog, DefaultDbContext>
{
    private readonly IApplicationContext applicationContext;
    public ProjectLockLogRepository(DefaultDbContext dbContext, IApplicationContext applicationContext) : base(dbContext, applicationContext)
    {
        this.applicationContext = applicationContext;
    }

    /// <summary>
    /// 获取列表
    /// </summary>
    /// <param name="query"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <returns></returns>
    public IPagedList<ProjectLockLog> GetProjectLockLogs(ProjectLockLogQuery query, int pageIndex, int pageSize)
    {
        Sql sql = Sql.Builder;
        sql.Select("project_lock_log.id")
            .From("project_lock_log");
        sql.InnerJoin("project as b").On("project_lock_log.project_id=b.project_id");
        #region 主管单位数据权限
        if (applicationContext.CurrentUser is IDeptUser deptUser && !deptUser.IsSuperAdministrator())
        {
            sql.InnerJoin("project as prj").On($"project_lock_log.project_id=prj.project_id and prj.is_deleted=0 and prj.industry_type=@0 ", deptUser.IndustryType);
            if (deptUser.Level == AdministrativeLevel.City)
                sql.Append($" and prj.city_code={deptUser.CityCode}");
            if (deptUser.Level == AdministrativeLevel.Area)
                sql.Append($" and prj.area_code={deptUser.AreaCode}");
        }
        #endregion
        if (!string.IsNullOrEmpty(query.Keywords))
            sql.Where("( b.name Like @0)", "%" + StringUtility.StripSQLInjection(query.Keywords) + "%");
        if (query.ProjectId.HasValue)
            sql.Where("project_lock_log.project_id =@0", query.ProjectId.Value);
        if (query.Month.HasValue)
            sql.Where("lock_month =@0", query.Month.Value.ToString("yyyy-MM-01"));
        if (query.DataSourse.HasValue)
            sql.Where("project_lock_log.data_sourse =@0", query.DataSourse.Value);
        if (query.HasLocked.HasValue)
            sql.Where("project_lock_log.has_locked =@0", query.HasLocked.Value);
        sql.OrderBy("project_lock_log.id DESC");
        return GetPagingEntities(pageSize, pageIndex, sql);
    }

    public IEnumerable<ProjectLockLog> GetProjectLockLogsByProjectId(int projectId)
    {
        int areaVersion = EntityCacheService.GetAreaVersion("ProjectId", projectId);
        return GetTopEntities(1000, CachingExpirationType.ObjectCollection, () =>
        {
            return $"ProjectLockLogsByProjectId:{projectId}:{areaVersion}";
        }, () =>
        {
            Sql sql = Sql.Builder
            .Select("id")
            .From("project_lock_log")
            .Where("project_id=@0", projectId);
            return sql;
        });
    }

    /// <summary>
    /// 分页查询，上锁记录不超过三次的数据
    /// </summary>
    /// <param name="query"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <returns></returns>
    public IPagedList<ProjectLockLog> GetProjectLockLogsByLock(ProjectLockLogQuery query, int pageIndex, int pageSize)
    {
        Sql sql = Sql.Builder;
        sql.Select("project_lock_log.id")
            .From("project_lock_log");
        sql.InnerJoin("project as b").On("project_lock_log.project_id=b.project_id");
        sql.InnerJoin("report_project_month as c").On("project_lock_log.project_id=c.project_id");
        #region 主管单位数据权限
        if (applicationContext.CurrentUser is IDeptUser deptUser && !deptUser.IsSuperAdministrator())
        {
            sql.InnerJoin("project as prj").On($"project_lock_log.project_id=prj.project_id and prj.is_deleted=0 and prj.industry_type=@0 ", deptUser.IndustryType);
            if (deptUser.Level == AdministrativeLevel.City)
                sql.Append($" and prj.city_code={deptUser.CityCode}");
            if (deptUser.Level == AdministrativeLevel.Area)
                sql.Append($" and prj.area_code={deptUser.AreaCode}");
        }
        #endregion
        sql.Where("project_lock_log.project_id not in(select project_id from project_lock_log group by project_id having count(1)>3)");
        if (!string.IsNullOrEmpty(query.Keywords))
            sql.Where("( b.name Like @0)", "%" + StringUtility.StripSQLInjection(query.Keywords) + "%");
        if (query.ProjectId.HasValue)
            sql.Where("project_lock_log.project_id =@0", query.ProjectId.Value);
        if (query.Month.HasValue)
            sql.Where("lock_month =@0", query.Month.Value.ToString("yyyy-MM-01"));
        if (query.DataSourse.HasValue)
            sql.Where("project_lock_log.data_sourse =@0", query.DataSourse.Value);
        if (query.HasLocked.HasValue)
            sql.Where("project_lock_log.has_locked =@0", query.HasLocked.Value);
        sql.Where("c.month =@0 and c.income_status=@1", DateTime.Now.ToString("yyyy-MM-01"), 落实状态.已落实);
        sql.OrderBy("project_lock_log.id DESC");
        return GetPagingEntities(pageSize, pageIndex, sql);
    }

    public ProjectLockLog? GetProjectLockLogByCode(string code)
    {
        Sql sql = Sql.Builder.Select("id").From("project_lock_log").Where("code=@0", code);
        var id = DbContext.FirstOrDefault<int>(sql);
        if (id == 0)
            return null;
        return Get(id);
    }
}